const elasticsearch = require("elasticsearch");
const fs = require("fs");
const type = "_doc";
class es {
  config;
  client;
  constructor(app) {
    this.config = app.config.es;
    this.client = new elasticsearch.Client(this.config);
    app.log.info(
      `elasticsearch loaded successfully, usage: this.app.es.client`,
      true
    );
  }
  async search(index, body) {
    const res = await this.client.search({
      index,
      type,
      body,
    });
    res.hits.hits.forEach((d) => {
      d._source.id = d._id;
    });
    return {
      total: res.hits.total.value,
      data: res.hits.hits.map((d) => {
        return d._source;
      }),
    };
  }
  async create(index, body, refresh = false, waitForActiveShards = 1) {
    return await this.client.index({
      index,
      type,
      refresh,
      waitForActiveShards,
      body,
    });
  }
  async count(index, body) {
    const res = await this.client.count({
      index,
      type,
      body,
    });
    return res.count;
  }
  //创建/更新索引
  async indexCreate(app) {
    const filePath = __dirname + "/../../../../esindex";
    const es = this;
    const exindexFileExists = fs.existsSync(filePath);
    if (!exindexFileExists) return;
    return require("young-require-all")({
      dirname: filePath,
      filter: /(.+)\.ts$/,
      resolve: async function (settings, filePath, fileName) {
        if (fileName == "client") {
          throw new Error(
            "elasticsearch index file [client] is keyword, not allowed!"
          );
        } else {
          const params = { index: fileName, body: settings };
          es.client.indices.exists(params).then(async (res) => {
            //更新
            if (res) {
              try {
                await es.client.indices.putMapping({
                  index: fileName,
                  body: settings.mappings,
                });
                app.log.info(
                  `elasticsearch index [${fileName}] updated successfully, usage: this.app.es.${fileName}`,
                  true
                );
              } catch (err) {
                app.log.error(
                  `elasticsearch index【${fileName}】 update failed：${err.message}`,
                  true
                );
              }
            } else {
              //新增
              try {
                await es.client.indices.create(params);
                app.log.info(
                  `elasticsearch index [${fileName}] created successfully, usage: this.app.es.${fileName}`,
                  true
                );
              } catch (err) {
                app.log.error(
                  `elasticsearch index【${fileName}】 create failed：${err.message}`,
                  true
                );
              }
            }
          });
          app.es[fileName] = es.esOperate(fileName);
        }
      },
    });
  }
  esOperate(index) {
    const search = (body) => {
      return this.search(index, body);
    };
    const create = (body, refresh = false, waitForActiveShards = 1) => {
      return this.create(index, body, refresh, waitForActiveShards);
    };
    const count = (body) => {
      return this.count(index, body);
    };
    return { search, create, count };
  }
}
module.exports = es;
